/*
	   Frame#  Action
	   ----------------
	   0-39    idle
	   40-46   running
	   47-60   getting shot but not falling (back bending)
	   61-66   getting shot in shoulder
	   67-73   jumping
	   74-95   idle
	   96-112  getting shot and falling down
	   113-122 idle
	   123-135 idle
	   136-154 crouch
	   155-161 crouch crawl
	   162-169 crouch adjust weapon (idle)
	   170-177 kneeling dying
	   178-185 falling back dying
	   186-190 falling forward dying
	   191-198 falling back slow dying
	*/

// model animation states
enum modelState_t
{
	MODEL_IDLE,		// idle animation
	MODEL_CROUCH,		// crouch animation
	MODEL_RUN,		// running animation
	MODEL_JUMP		// jumping animation
};


typedef struct 
{
	int width;					// width of texture
	int height;					// height of texture
	double scaledWidth;
	double scaledHeight;

	unsigned int texID;			// the texture object id of this texture
	unsigned char *data;		// the texture data
	unsigned char *palette;
} texture_t;


// only partial pcx file header
typedef struct
{
	unsigned char manufacturer;
	unsigned char version;
	unsigned char encoding;
	unsigned char bits;
	unsigned char xMin;
	unsigned char yMin;
	unsigned char xMax;
	unsigned char yMax;
	unsigned char *palette;
} PCXHEADER;

// a single vertex
typedef struct
{
   float point[3];
} vector_t;


/* 
	MD2 Model Functionality
*/


// texture coordinate
typedef struct
{
   float s;
   float t;
} texCoord_t;

// texture coordinate index
typedef struct
{
   short s;
   short t;
} stIndex_t;

// info for a single frame point
typedef struct
{
   unsigned char v[3];
   unsigned char normalIndex;	// not used
} framePoint_t;

// information for a single frame
typedef struct
{
   float scale[3];
   float translate[3];
   char name[16];
   framePoint_t fp[1];
} frame_t;

// data for a single triangle
typedef struct
{
   unsigned short meshIndex[3];		// vertex indices
   unsigned short stIndex[3];		// texture coordinate indices
} mesh_t;

typedef struct
{
   int ident;		 // identifies as MD2 file "IDP2"
   int version;	 // mine is 8
   int skinwidth;    // width of texture
   int skinheight;   // height of texture
   int framesize;    // number of bytes per frame
   int numSkins;     // number of textures
   int numXYZ;       // number of points
   int numST;        // number of texture
   int numTris;      // number of triangles
   int numGLcmds;
   int numFrames;    // total number of frames
   int offsetSkins;  // offset to skin names (64 bytes each)
   int offsetST;     // offset of texture s-t values
   int offsetTris;   // offset of triangle mesh
   int offsetFrames; // offset of frame data (points)
   int offsetGLcmds; // type of OpenGL commands to use
   int offsetEnd;    // end of file
} modelHeader_t;


class CMD2Model
{
private:

	int numFrames;			// number of model frames
	int numVertices;         // number of vertices
	int numTriangles;        // number of triangles
	int numST;               // number of skins
	int frameSize;           // size of each frame in bytes
	int currentFrame;        // current frame # in animation
	int nextFrame;           // next frame # in animation
	float interpol;          // percent through current frame
	mesh_t *triIndex;        // triangle list
	texCoord_t *st;          // texture coordinate list
	vector_t *vertexList;    // vertex list
	texture_t *modelTex;     // texture data
	modelState_t modelState;	// current model animation state

public:

     CMD2Model();        // constructor
     ~CMD2Model();       // destructor
	
	 // load PCX File
	 __declspec(dllexport) unsigned char *LoadPCXFile(char *filename, PCXHEADER *pcxHeader);

 	 // load PCX Texture
 	 __declspec(dllexport) texture_t *LoadPCXTexture(char *filename);

     // load model and skin/texture at the same time
     __declspec(dllexport) int Load(char *modelFile, char *skinFile);

	 // setup skin
     __declspec(dllexport) void SetupSkin(texture_t *thisTexture);

     // render model with interpolation to get animation
     __declspec(dllexport) int Animate(int startFrame, int endFrame, float percent);

     // free memory of model
    static __declspec(dllexport) int Unload();

	// set animation state of model
	__declspec(dllexport) int SetState(modelState_t state);	

	// retrieve animation state of model
	__declspec(dllexport) modelState_t GetState();
};
